// 文章数据模型
const { postgresPool, redisClient } = require('../config/database');
const { DataConsistency } = require('../consistency');

class Article {
    constructor(data) {
        this.id = data.id;
        this.title = data.title;
        this.category = data.category;
        this.theme = data.theme;
        this.keywords = data.keywords;
        this.content = data.content;
        this.status = data.status || 'draft';
        this.authorId = data.author_id;
        this.createdAt = data.created_at;
        this.updatedAt = data.updated_at;
        this.publishedAt = data.published_at;
        this.checksum = data.checksum;
        this.metadata = data.metadata || {};
    }

    // 生成数据校验和
    generateChecksum() {
        const dataToHash = `${this.title}${this.content}${this.status}${this.authorId}`;
        return DataConsistency.generateChecksum(dataToHash);
    }

    // 创建文章
    static async create(articleData) {
        const client = await postgresPool.connect();
        
        try {
            // 生成校验和
            const checksum = DataConsistency.generateChecksum(
                `${articleData.title}${articleData.content}${articleData.status}${articleData.authorId}`
            );
            
            const query = `
                INSERT INTO articles (title, category, theme, keywords, content, status, author_id, checksum, metadata)
                VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
                RETURNING *
            `;
            
            const values = [
                articleData.title,
                articleData.category,
                articleData.theme,
                articleData.keywords,
                articleData.content,
                articleData.status || 'draft',
                articleData.authorId,
                checksum,
                JSON.stringify(articleData.metadata || {})
            ];
            
            const result = await client.query(query, values);
            const article = new Article(result.rows[0]);
            
            // 更新缓存
            await this.updateCache(article);
            
            return article;
        } finally {
            client.release();
        }
    }

    // 根据ID查找文章
    static async findById(id, useCache = true) {
        // 尝试从缓存获取
        if (useCache) {
            const cached = await redisClient.get(`article:${id}`);
            if (cached) {
                return new Article(JSON.parse(cached));
            }
        }
        
        const client = await postgresPool.connect();
        
        try {
            const query = 'SELECT * FROM articles WHERE id = $1';
            const result = await client.query(query, [id]);
            
            if (result.rows.length === 0) {
                return null;
            }
            
            const article = new Article(result.rows[0]);
            
            // 更新缓存
            await this.updateCache(article);
            
            return article;
        } finally {
            client.release();
        }
    }

    // 更新文章
    async update(updateData) {
        const client = await postgresPool.connect();
        
        try {
            const fields = [];
            const values = [];
            let paramCount = 1;
            
            if (updateData.title !== undefined) {
                fields.push(`title = $${paramCount++}`);
                values.push(updateData.title);
            }
            if (updateData.category !== undefined) {
                fields.push(`category = $${paramCount++}`);
                values.push(updateData.category);
            }
            if (updateData.theme !== undefined) {
                fields.push(`theme = $${paramCount++}`);
                values.push(updateData.theme);
            }
            if (updateData.keywords !== undefined) {
                fields.push(`keywords = $${paramCount++}`);
                values.push(updateData.keywords);
            }
            if (updateData.content !== undefined) {
                fields.push(`content = $${paramCount++}`);
                values.push(updateData.content);
            }
            if (updateData.status !== undefined) {
                fields.push(`status = $${paramCount++}`);
                values.push(updateData.status);
                
                // 如果是发布状态，设置发布时间
                if (updateData.status === 'published') {
                    fields.push(`published_at = CURRENT_TIMESTAMP`);
                }
            }
            if (updateData.metadata !== undefined) {
                fields.push(`metadata = $${paramCount++}`);
                values.push(JSON.stringify(updateData.metadata));
            }
            
            if (fields.length === 0) {
                return this;
            }
            
            // 生成新的校验和
            const newChecksum = this.generateChecksum();
            fields.push(`checksum = $${paramCount++}`);
            values.push(newChecksum);
            
            fields.push(`updated_at = CURRENT_TIMESTAMP`);
            values.push(this.id);
            
            const query = `
                UPDATE articles 
                SET ${fields.join(', ')}
                WHERE id = $${paramCount}
                RETURNING *
            `;
            
            const result = await client.query(query, values);
            const updatedArticle = new Article(result.rows[0]);
            
            // 更新缓存
            await this.constructor.updateCache(updatedArticle);
            
            return updatedArticle;
        } finally {
            client.release();
        }
    }

    // 删除文章
    async delete() {
        const client = await postgresPool.connect();
        
        try {
            const query = 'DELETE FROM articles WHERE id = $1';
            await client.query(query, [this.id]);
            
            // 清除缓存
            await redisClient.del(`article:${this.id}`);
            
            return true;
        } finally {
            client.release();
        }
    }

    // 获取所有文章（分页）
    static async findAll(page = 1, limit = 10, filters = {}) {
        const client = await postgresPool.connect();
        
        try {
            const offset = (page - 1) * limit;
            const whereConditions = [];
            const values = [limit, offset];
            let paramCount = 3;
            
            if (filters.status) {
                whereConditions.push(`status = $${paramCount++}`);
                values.push(filters.status);
            }
            if (filters.category) {
                whereConditions.push(`category = $${paramCount++}`);
                values.push(filters.category);
            }
            if (filters.authorId) {
                whereConditions.push(`author_id = $${paramCount++}`);
                values.push(filters.authorId);
            }
            
            const whereClause = whereConditions.length > 0 ? 
                `WHERE ${whereConditions.join(' AND ')}` : '';
            
            const query = `
                SELECT * FROM articles 
                ${whereClause}
                ORDER BY created_at DESC 
                LIMIT $1 OFFSET $2
            `;
            
            const countQuery = `
                SELECT COUNT(*) FROM articles 
                ${whereClause}
            `;
            
            const [articlesResult, countResult] = await Promise.all([
                client.query(query, values),
                client.query(countQuery, values.slice(2))
            ]);
            
            return {
                articles: articlesResult.rows.map(row => new Article(row)),
                total: parseInt(countResult.rows[0].count),
                page,
                limit,
                totalPages: Math.ceil(parseInt(countResult.rows[0].count) / limit)
            };
        } finally {
            client.release();
        }
    }

    // 更新缓存
    static async updateCache(article) {
        await redisClient.setex(
            `article:${article.id}`,
            3600, // 1小时缓存
            JSON.stringify(article)
        );
    }

    // 验证数据一致性
    async verifyConsistency() {
        const currentChecksum = this.generateChecksum();
        return currentChecksum === this.checksum;
    }
}

module.exports = Article;